import {
  createContext,
  useReducer,
} from 'react'
import type {
  Context,
  Reducer,
  Dispatch,
  PropsWithChildren,
  ReactElement,
} from 'react'

export const ctxCreator = <S, A>(reducer: Reducer<S, A>, initialState: S): Readonly<[
  Context<{ state: S; dispatch: Dispatch<A> }>,
  (props: PropsWithChildren<Partial<S>>) => ReactElement,
]> => {
  const defaultDispatch: Dispatch<A> = () => initialState
  const ctx = createContext({
    state: initialState,
    dispatch: defaultDispatch,
  })
  function Provider(props: PropsWithChildren<Partial<S>>) {
    const { children, ...restProps } = props
    const [state, dispatch] = useReducer<Reducer<S, A>>(reducer, initialState)
    return (
      <ctx.Provider
        value={{
          state: {
            ...state,
            ...restProps,
          },
          dispatch,
        }}
      >
        {children}
      </ctx.Provider>
    )
  }
  return [ctx, Provider] as const
}
